#include "lpcc.h"

void lpcc(const double x[], int N, double lp[], int p = 12, int L = 12) {
    double * ar = new double[p+1];
    lpc(x,N,ar,p);
    for(int i = p; i >= 1; -- i) {
        ar[i] = ar[i-1];
    }
    lp[1] = ar[1];
    for(int n = 2; n <= p; ++ n) {
        lp[n] = ar[n];
        for(int l = 1; l <= n-1; ++ l) {
            lp[n] = lp[n] + ar[l] * lp[n-l]*(n-l)/n;
        }
    }
    for(int n = p+1; n <= L; ++ n) {
        lp[n] = 0;
        for(int l = 1; l <= p; ++ l) {
            lp[n] = lp[n] + ar[l] * lp[n-l] * (n-l) / n;
        }
    }
    for(int n = 1; n <= L; ++ n) {
        lp[n] = -lp[n];
    }
    delete(ar);
}

void lpcc(const std::vector<double> & x, std::vector<double> & lp, int p = 12, int L = 12) {
    std::vector<double> ar;
    lpc(x,ar,p);
    lp.resize(L+1, 0);

    for(int i = p; i >= 1; -- i) {
        ar[i] = ar[i-1];
    }
    lp[1] = ar[1];
    for(int n = 2; n <= p; ++ n) {
        lp[n] = ar[n];
        for(int l = 1; l <= n-1; ++ l) {
            lp[n] = lp[n] + ar[l] * lp[n-l]*(n-l)/n;
        }
    }
    for(int n = p+1; n <= L; ++ n) {
        lp[n] = 0;
        for(int l = 1; l <= p; ++ l) {
            lp[n] = lp[n] + ar[l] * lp[n-l] * (n-l) / n;
        }
    }
    for(int n = 1; n <= L; ++ n) {
        lp[n] = -lp[n];
    }
}
